package scenic.path;

import java.awt.Rectangle;

import scenic.geom.Affine2;
import scenic.geom.Double2;

/**
 * A subpath defines a continuous path which consists of
 * different kinds of segments. If a subpath is closed its
 * end point is connected to the start point with a straight
 * line.
 */
public class SubPath {
	private double startX;
	private double startY;
	private Segment[] segments;
	private boolean closed;
	
	/**
	 * Creates a new subpath with the given start point and segments.
	 * 
	 * @param startX x coordinate of the start point.
	 * @param startY y coordinate of the start point.
	 * @param segments the segments.
	 * @param closed defines is the subpath closed.
	 */
	public SubPath(double startX, double startY, Segment[] segments, 
			boolean closed) {
		this.startX = startX;
		this.startY = startY;
		this.segments = segments;
		this.closed = closed;
	}
	
	/**
	 * Gets the x coordinate of the start point.
	 */
	public double getStartX() {
		return startX;
	}

	/**
	 * Gets the y coordinate of the start point.
	 */
	public double getStartY() {
		return startY;
	}

	/**
	 * Gets is the subpath closed.
	 */
	public boolean isClosed() {
		return closed;
	}

	/**
	 * Gets the segments.
	 */
	public Segment[] getSegments() {
		return (Segment[])segments.clone();
	}

	/**
	 * Walks the given walker through this subpath.
	 * 
	 * @param walker the walker.
	 * @param error the error matrix.
	 */
	public void walk(PathWalker walker, Affine2 error) {
		Double2 position = new Double2(startX, startY);

		walker.beginSubPath(closed);
		walker.lineTo(startX, startY);
		for(int i = 0; i < segments.length; i++)
			segments[i].walk(walker, position, error);
		walker.endSubPath();
	}
	
	/**
	 * Gets the bounds of this subpath using the given transform.
	 * 
	 * @param transform the transform
	 * @param r the bounds.
	 */
	public void getBounds(Affine2 transform, Rectangle r) {
		Double2 position = new Double2(startX, startY);

		Path.addPointToBounds(transform, r, startX, startY);
		for(int i = 0; i < segments.length; i++)
			segments[i].getBounds(transform, r, position);
	}
	
}
